package com.zeus.base.smscenter.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by ShanFei on 2017-03-07.
 * 自定义shiro认证过滤器
 */
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
    private static final Logger log = LoggerFactory.getLogger(CustomFormAuthenticationFilter.class);
    /**
     *所有请求都会经过的方法
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (isLoginRequest(request, response)) {
            if (isLoginSubmission(request, response)) {
                if (log.isTraceEnabled()) {
                    log.trace("Login submission detected.  Attempting to execute login.");
                }
                if (!ShiroAjaxUtil.isAjax(request)) {// 不是ajax请求
                    String vcode = request.getParameter("vcode");
                    HttpServletRequest httpservletrequest = (HttpServletRequest) request;
                    String vvcode = (String) httpservletrequest.getSession().getAttribute("success");
                    if (vvcode == null || "".equals(vvcode) || !vvcode.equals(vcode)) {
                        Map<String,String> resultMap = new HashMap<String, String>();
                        resultMap.put("success","false");
                        resultMap.put("message","验证码错误");
                        ShiroAjaxUtil.out(response,resultMap);
                        return false;
                    }
                }
                return executeLogin(request, response);
            } else {
                if (log.isTraceEnabled()) {
                    log.trace("Login page view.");
                }
                return true;
            }
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Attempting to access a path which requires authentication.  Forwarding to the " + "Authentication url [" + getLoginUrl() + "]");
            }
            if (!ShiroAjaxUtil.isAjax(request)) {// 不是ajax请求
                saveRequestAndRedirectToLogin(request, response);
            } else {
                Map<String,String> resultMap = new HashMap<String, String>();
                resultMap.put("code", ShiroError.LoginFailedException);
                resultMap.put("success","false");
                resultMap.put("message","登录过期或未登陆");
                ShiroAjaxUtil.out(response,resultMap);
            }
            return false;
        }
        //return super.onAccessDenied(request, response);
    }

    /**
     * shiro认认成功
     * @param token
     * @param subject
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        //WebUtils.getAndClearSavedRequest(request);
        //WebUtils.redirectToSavedRequest(request,response,getSuccessUrl());
        //return false;
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        if (!ShiroAjaxUtil.isAjax(request)) {// 不是ajax请求
            issueSuccessRedirect(request, response);
        } else {
            Map<String,String> resultMap = new HashMap<String, String>();
            resultMap.put("success","true");
            resultMap.put("message","登陆成功");
            ShiroAjaxUtil.out(httpServletResponse,resultMap);
        }
        return false;
        //return super.onLoginSuccess(token, subject, request, response);
    }

    /**
     * shiro认证失败
     * @param token
     * @param e
     * @param request
     * @param response
     * @return
     */
    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        if (!ShiroAjaxUtil.isAjax(request)) {// 不是ajax请求
            setFailureAttribute(request, e);
            return true;
        }
        try {
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            String message = e.getClass().getSimpleName();
            Map<String,String> resultMap = new HashMap<String, String>();
            if ("IncorrectCredentialsException".equals(message)) {
                resultMap.put("success","false");
                resultMap.put("message","密码错误");
                ShiroAjaxUtil.out(response,resultMap);
            } else if ("UnknownAccountException".equals(message)) {
                resultMap.put("success","false");
                resultMap.put("message","账号不存在");
                ShiroAjaxUtil.out(response,resultMap);
            } else if ("LockedAccountException".equals(message)) {
                resultMap.put("success","false");
                resultMap.put("message","账号被锁定");
                ShiroAjaxUtil.out(response,resultMap);
            } else {
                resultMap.put("success","false");
                resultMap.put("message","未知错误");
                ShiroAjaxUtil.out(response,resultMap);
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return false;
        //return super.onLoginFailure(token, e, request, response);
    }
}
